package com.deng.springboot.demo.web.advice;

import com.deng.springboot.demo.common.util.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;

/**
 * @author 邓力宾
 * @date 2020/3/119:49
 * @Description:
 */
@ControllerAdvice(basePackages = {"com.deng.springboot.demo.web.controller"})
public class ControllerRequestBodyAdvice implements RequestBodyAdvice {
    private Logger logger = LoggerFactory.getLogger(getClass());
    /**
     * 返回true才会进行拦截
     * 可以根据方法上是否具有某个注解返回true或false
     * 如:
     * return methodParameter.getMethodAnnotation(***.class) != null //方法注解
     *                 && methodParameter.getParameterAnnotation(RequestBody.class) != null; //参数注解
     * @param methodParameter
     * @param type
     * @param aClass
     * @return
     */
    @Override
    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return false; // 开发环境可以打开 返回true
    }

    /**
     * spring 回调该方法 可以获取请求的RequestBody数据
     * @param httpInputMessage
     * @param methodParameter
     * @param type
     * @param aClass
     * @return
     * @throws IOException
     */
    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
        InputStream body = httpInputMessage.getBody();
        InputStreamReader isr = new InputStreamReader(body,"UTF-8");
        char[] buf = new char[1024];
        StringBuilder sb = new StringBuilder();
        int len;
        while((len = (isr.read(buf,0,buf.length))) !=-1){
            sb.append(buf,0,len);
        }
        isr.close();
        String s = sb.toString(); // 获取请求的数据
        logger.info("请求数据:"+s);

        /*根据需要 对数据进行处理 返回处理后的数据*/
        //s = "do something";
        return new HttpInputMessage() { // 原来的inputStream输入流已经关闭了不能直接返回原来的，这里重新创建一个
            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream(s.getBytes("UTF-8"));
            }
            @Override
            public HttpHeaders getHeaders() {
                return httpInputMessage.getHeaders();
            }
        };


    }

    /**
     * 请求参数被读取，转为对象后 回调该方法
     * @param o
     * @param httpInputMessage
     * @param methodParameter
     * @param type
     * @param aClass
     * @return
     */
    @Override
    public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
       // logger.info("afterBodyRead=>:"+ JsonUtils.toJsonString(o)); // 获取RequestBody转成的对象
        return o;
    }

    @Override
    public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return o;
    }
}
